﻿using System;
using System.Collections.Generic;
using System.Linq;
using NHibernate;
using NHibernate.Criterion;
using NHibernate.Linq;

namespace BankCreditPortfolio.DAL.Services
{
    public class DataService<TEntity>
    {
        private ISession _session;

        public DataService()
        {
            _session = NHibernateHelper.OpenSession();
        }

        public virtual ISession Session
        {
            get
            {
                return _session;
            }
        }

        public virtual TEntity Find(int id)
        {
            var entity = Session.Get<TEntity>(id);

            return entity;
        }

        public virtual IEnumerable<TEntity> GetAll()
        {
            ICriteria criteria = Session.CreateCriteria(typeof(TEntity));
            return criteria.List<TEntity>();
        }

        public virtual IEnumerable<TEntity> GetPaged(int page, int pageSize)
        {
            ICriteria criteria = Session.CreateCriteria(typeof(TEntity));
            criteria.SetFirstResult(page * pageSize);
            criteria.SetMaxResults(pageSize);
            return criteria.List<TEntity>();
        }

        public virtual long Count(ICriteria criteria)
        {
            var countCriteria = (ICriteria)criteria.Clone();
            countCriteria.SetProjection(Projections.RowCount());
            long count;
            Int64.TryParse(countCriteria.List()[0].ToString(), out count);
            return count;
        }

        public virtual bool Save(ref TEntity entity)
        {
            Session.SaveOrUpdate(entity);
            Session.Flush();
            return true;
        }

        public virtual bool Update(ref TEntity entity)
        {
            Session.Merge(entity);
            Session.Flush();
            return true;
        }

        public virtual bool Delete(TEntity entity)
        {
            try
            {
                Session.Delete(entity);
                Session.Flush();
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public void DeleteAll()
        {
            Session.Delete(String.Format("from {0}", typeof(TEntity).Name));
            Session.Flush();
        }

        public virtual IQueryable<TEntity> CreateQuery()
        {
            return Session.Query<TEntity>();
        }
    }
}